export interface QueueStatus {
  concurrency: number
  running: number
  pending: number
  isIdle: boolean
}

export class QueueHandler {
  private concurrency: number
  private running: number = 0
  private paused: boolean = false
  private queue: Array<{
    task: () => Promise<any>
    resolve: (value: any) => void
    reject: (reason?: any) => void
  }> = []

  constructor(concurrency: number = 1) {
    this.checkConcurrency(concurrency)
    this.concurrency = concurrency
  }

  /**
   * 添加任务到队列
   * @param task 要执行的任务函数
   * @returns Promise，任务完成时解析
   */
  add<T = any>(task: () => Promise<T>): Promise<T> {
    return new Promise<T>((resolve, reject) => {
      this.queue.push({
        task: task as () => Promise<any>,
        resolve: resolve as (value: any) => void,
        reject,
      })
      this.next()
    })
  }

  /**
   * 批量添加多个任务
   * @param tasks 任务数组
   * @returns Promise，所有任务完成时解析
   */
  addAll<T = any>(tasks: Array<() => Promise<T>>): Promise<T[]> {
    return Promise.all(tasks.map(task => this.add(task)))
  }

  /**
   * 处理队列中的下一个任务
   */
  private next(): void {
    // 检查是否可以执行新任务
    if (this.running >= this.concurrency || this.queue.length === 0)
      return

    this.running++
    const { task, resolve, reject } = this.queue.shift()!

    Promise.resolve()
      .then(() => task())
      .then((result) => {
        resolve(result)
        return result
      })
      .catch((error) => {
        reject(error)
        throw error // 重新抛出以触发 finally
      })
      .finally(() => {
        this.running--
        this.next() // 处理下一个任务
      })
  }

  /**
   * 等待队列空闲（所有任务完成）
   * @returns Promise，队列空闲时解析
   */
  onIdle(): Promise<void> {
    return new Promise((resolve) => {
      // 如果已经空闲，立即解析
      if (this.isIdle) {
        resolve()
        return
      }

      // 定期检查状态
      const checkIdle = () => {
        if (this.isIdle) {
          resolve()
        }
        else {
          setTimeout(checkIdle, 10)
        }
      }
      checkIdle()
    })
  }

  /**
   * 等待队列空闲（使用微任务优化）
   */
  async onIdleMicro(): Promise<void> {
    while (!this.isIdle) {
      await new Promise(resolve => setTimeout(resolve, 0))
    }
  }

  /**
   * 清空队列中的所有待处理任务
   * @param reason 清空原因，会作为拒绝原因
   */
  clear(reason: string = 'Queue cleared'): void {
    const pendingTasks = [...this.queue]
    this.queue = []

    // 拒绝所有待处理任务
    pendingTasks.forEach(({ reject }) => {
      reject(new Error(reason))
    })
  }

  /**
   * 获取队列当前状态
   */
  get status(): QueueStatus {
    return {
      concurrency: this.concurrency,
      running: this.running,
      pending: this.queue.length,
      isIdle: this.isIdle,
    }
  }

  /**
   * 检查队列是否空闲
   */
  get isIdle(): boolean {
    return this.running === 0 && this.queue.length === 0
  }

  /**
   * 获取正在运行的任务数量
   */
  get runningCount(): number {
    return this.running
  }

  /**
   * 获取等待中的任务数量
   */
  get pendingCount(): number {
    return this.queue.length
  }

  /**
   * 获取队列大小（运行中 + 等待中）
   */
  get size(): number {
    return this.running + this.queue.length
  }

  /**
   * 暂停队列（停止处理新任务）
   */
  pause(): void {
    this.paused = true
  }

  /**
   * 恢复队列处理
   */
  resume(): void {
    this.paused = false
    this.next() // 立即尝试处理下一个任务
  }

  /**
   * 检查队列是否暂停
   */
  get isPaused(): boolean {
    return this.paused
  }

  /**
   * 检查并发数是否有效
   * @param concurrency 要设置的并发数
   */
  checkConcurrency(concurrency: number): void {
    if (concurrency < 1) {
      throw new Error('Concurrency must be at least 1')
    }

    if (this.running >= concurrency) {
      throw new Error('Concurrency limit reached')
    }
  }

  /**
   * 修改并发数（动态调整）
   */
  setConcurrency(newConcurrency: number): void {
    this.checkConcurrency(newConcurrency)

    this.concurrency = newConcurrency

    // 如果提高了并发数，立即处理更多任务
    while (this.running < this.concurrency && this.queue.length > 0) {
      this.next()
    }
  }
}
